import GameData, { Group } from "../Data/GameData";
import Hole from "../People/Hole";
import Wood from "../People/Wood";
import GameUI from "../UIs/GameUI";
import MainUI from "../UIs/MainUI";

const {ccclass, property} = cc._decorator;

@ccclass
export default class GameManager extends cc.Component {
    private static instance:GameManager;
    static get Instance(){
        return this.instance;
    }

    @property(cc.Node)
    Levels:cc.Node;
    @property(cc.Label)
    levelLabel:cc.Label;

    woodArr:cc.Node[] = [];

    levelNum = 0;
    isMoving = false;
    level:cc.Node;
    currentNail:cc.Node;
    lock:cc.Node;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        GameManager.instance = this;
        cc.director.getPhysicsManager().enabled = true; // 开启了物理引擎
        cc.director.getCollisionManager().enabled = true;
        // cc.director.getPhysicsManager().debugDrawFlags = true;
    }

    start () {
        this.LevelInit();
    }

    LevelInit(){
        this.levelNum = MainUI.Instance.levelNum;
        this.level = this.Levels.children[this.levelNum];
        this.levelLabel.string = "第" + (this.levelNum + 1).toString() + "关";
        this.level.active = true;
        this.level.children.forEach(item => {
            if(item.group == Group.HWood || item.group == Group.VWood) this.woodArr.push(item);
            else if(item.group == Group.Lock) this.lock = item;
        });
    }

    TouchNail(event:cc.Event){
        if(!this.currentNail){
            this.currentNail = event.target;
            this.PopNail();
        }
        else this.PushNail();
    }

    TouchHole(event:cc.Event){
        if(!this.currentNail) return;
        this.isMoving = true;
        var node:cc.Node = event.target;
        var hole = node.getComponent(Hole);
        var collider =  this.currentNail.getComponent(cc.PhysicsCollider);
        if(hole.catchWood.length == 0){
            this.currentNail.group = Group.default;
            collider.apply();
            var upNail = this.currentNail.children[1];
            var worldPos = this.level.convertToWorldSpaceAR(node.position);
            var localPos = this.currentNail.convertToNodeSpaceAR(worldPos);
            cc.tween(upNail)
            .to(0.5, {position:localPos})
            .call(()=>{
                this.DisableJoints();
                this.currentNail.position = node.position;
                upNail.position = cc.Vec3.ZERO;
                this.currentNail.group = Group.Nail;
                collider.apply();
                this.PushNail();
            }, this)
            .start();
        }
        else{
            this.currentNail.group = Group.Nail;
            collider.apply();
            var group:string;
            var woods:cc.Node[] = [];
            var holesNum:number[] = [];
            hole.catchWood.forEach(item => {
                for (var i = 0; i < item.children.length; i++) {
                    var woodHole = item.children[i];
                    var pos = cc.v2(item.convertToWorldSpaceAR(woodHole.position));
                    var holePos = cc.v2(this.level.convertToWorldSpaceAR(node.position));
                    var distance = cc.Vec2.distance(pos, holePos);
                    if(distance < 10){
                        woods.push(item);
                        holesNum.push(i);
                        if(item.group == Group.HWood){
                            if(group == Group.NailInVWood) group = Group.default;
                            else {
                                group = Group.NailInHWood;
                            }
                        }
                        else{
                            if(group == Group.NailInHWood) group = Group.default;
                            else {
                                group = Group.NailInVWood;
                            }
                        }
                        this.currentNail.group = Group.default;
                        break;
                    }
                }
            });
            if(woods.length < hole.catchWood.length) return this.PushNail();
            if(woods.length > 0){
                var upNail = this.currentNail.children[1];
                var worldPos = this.level.convertToWorldSpaceAR(node.position);
                var localPos = this.currentNail.convertToNodeSpaceAR(worldPos);
                cc.tween(upNail)
                .to(0.5, {position:localPos})
                .call(()=>{
                    this.DisableJoints();
                    this.currentNail.position = node.position;
                    upNail.position = cc.Vec3.ZERO;
                    this.currentNail.group = group;
                    collider.apply();
                    for (var i = 0; i < woods.length; i++) {
                        var item = woods[i];
                        var joint = this.currentNail.getComponents(cc.RevoluteJoint)[i];
                        joint.connectedBody = item.getComponent(cc.RigidBody);
                        var woodHole = item.children[holesNum[i]]
                        joint.connectedAnchor = cc.Vec2.multiplyScalar(joint.connectedAnchor, cc.v2(woodHole.position), GameData.scales[GameManager.Instance.levelNum]);
                        joint.enabled = true;
                        joint.apply();
                    }
                    this.PushNail();
                }, this)
                .start();
            }
            else this.PushNail();
        }
    }

    DisableJoints(){
        var joints = this.currentNail.getComponents(cc.RevoluteJoint);
        for (var i = 0; i < joints.length; i++) {
            var joint = joints[i];
            joint.enabled = false;
            joint.connectedBody = null;
        }
    }

    PushNail(){
        this.currentNail.children[0].active = true;
        this.currentNail.children[1].active = false;
        this.currentNail = null;
        this.isMoving = false;
    }

    PopNail(){
        this.currentNail.children[0].active = false;
        this.currentNail.children[1].active = true;
    }

    SpliceWoodArr(start:number, delectCount:number){
        this.woodArr.splice(start, delectCount);
        if(this.woodArr.length == 0) GameUI.Instance.Victory();
    }

    Unlock(key:cc.Node){
        cc.tween(key)
        .to(0.5, {position:this.lock.position})
        .call(()=>{
            key.active = false;
            this.lock.active = false;
        })
        .start();
    }
}
